#include "mqtt_src.h"



char create_connect_msg(struct Mqtt_info* mq) {
	unsigned short lenClientID = 0;
	unsigned short lenName = 0;
	unsigned short lenpassWord = 0;
	int index = 0;
	unsigned char* temp_pbuf = mq->pbuf;
	int encodeByte = 0;
	memset(mq->pbuf, 0, pbuf_MAX_SIZE);				//clear msg 

	lenClientID = strlen(mq->clientID);
	if (mq->userName) {
		lenName = strlen(mq->userName);
	}

	if (mq->Password) {
		lenpassWord = strlen(mq->Password);
	}
	mq->dataSize = lenName + lenpassWord + lenClientID + 2 + (lenName==0?0:2)+(lenpassWord==0?0:2) + 10;

	temp_pbuf[index++] = 0x10;

	do {
		encodeByte = mq->dataSize % 128;
		mq->dataSize = mq->dataSize / 128;
		if (mq->dataSize > 0) {
			encodeByte = encodeByte | 0x80;
		}
		temp_pbuf[index++] = encodeByte;
	} while (mq->dataSize > 0);

	temp_pbuf[index++] = 0;
	temp_pbuf[index++] = 4;

	temp_pbuf[index++] = 'M';
	temp_pbuf[index++] = 'Q';
	temp_pbuf[index++] = 'T';
	temp_pbuf[index++] = 'T';

	temp_pbuf[index++] = 4;					// MQTT3.1.1 protocol

	encodeByte = 0;
	if (lenName !=0) {
		encodeByte |= 0x80;
	}
	if (lenpassWord != 0) {
		encodeByte |= 0x40;
	}
	encodeByte |= 0x02;
	encodeByte |= (mq->QoS) << 3;
	temp_pbuf[index++] = encodeByte;

	temp_pbuf[index++] = (mq->liveTime>>8)&0xff;
	temp_pbuf[index++] = mq->liveTime&0xff;

	temp_pbuf[index++] = (lenClientID >> 8) & 0xff;
	temp_pbuf[index++] = lenClientID & 0xff;

	memcpy(&temp_pbuf[index], mq->clientID, lenClientID);
	index += lenClientID;

	if (lenName > 0) {
		temp_pbuf[index++] = (lenName >> 8) & 0xff;
		temp_pbuf[index++] = lenName & 0xff;

		memcpy(&temp_pbuf[index], mq->userName, lenName);
		index += lenName;
	}

	if (lenpassWord > 0) {
		temp_pbuf[index++] = (lenpassWord >> 8) & 0xff;
		temp_pbuf[index++] = lenpassWord & 0xff;

		memcpy(&temp_pbuf[index], mq->Password, lenpassWord);
		index += lenpassWord;
	}
	mq->dataSize = index;

	return 0;

}


void create_subscribeTopic_msg(struct Mqtt_info* mq, const char * topic ,QoSLevel Qos) {

	int index = 0;
	unsigned char* temp_pbuf = mq->pbuf;
	int lenTopic = 0;
	char encode = 0;

	memset(mq->pbuf, 0, pbuf_MAX_SIZE);
	lenTopic = strlen(topic);

	mq->dataSize = 2 + 2 + lenTopic + 1 ;

	temp_pbuf[index++] = 0x82;
	
	do {
		encode = mq->dataSize % 128;
		mq->dataSize = mq->dataSize / 128;
		if (mq->dataSize > 0) {
			encode = encode | 0x80;
		}
		temp_pbuf[index++] = encode;
	} while (mq->dataSize > 0);

	temp_pbuf[index++] = 0x00;
	temp_pbuf[index++] = (0x08|0x02);

	temp_pbuf[index++] = (lenTopic>>8)&0xff;
	temp_pbuf[index++] =  lenTopic&0xff;

	memcpy(&temp_pbuf[index], topic, lenTopic);
	index += lenTopic;

	temp_pbuf[index++] = Qos & 0xff;

	mq->dataSize = index;

}

void create_keepLive_msg(struct Mqtt_info* mq) {
	memset(mq->pbuf,0,pbuf_MAX_SIZE);
	mq->pbuf[0] = (0x80 | 0x40);
	mq->pbuf[1] = 0x00;
	mq->dataSize = 2;
}

void create_publishNew_msg(struct Mqtt_info* mq,const char* topic, const char* news) {
	int index = 0;
	unsigned char* temp_pbuf = mq->pbuf;
	int lenTopic = 0;
	int lenNews = 0;
	unsigned char encode = 0;
	lenTopic = strlen(topic);
	lenNews = strlen(news);

	mq->dataSize = 2 + lenTopic + lenNews;

	memset(temp_pbuf, 0, pbuf_MAX_SIZE);
	
	temp_pbuf[index++] = 0x30;

	do {
		encode = mq->dataSize % 128;
		mq->dataSize = mq->dataSize / 128;

		if (mq->dataSize > 0) {
			encode = encode | 0x80;
		}
		temp_pbuf[index++] = encode;

	} while (mq->dataSize > 0);

	temp_pbuf[index++] = (lenTopic>>8)&0xff;
	temp_pbuf[index++] = lenTopic&0xff;

	memcpy(&temp_pbuf[index], topic, lenTopic);
	index += lenTopic;

	memcpy(&temp_pbuf[index], news, lenNews);
	index += lenNews;
	mq->dataSize = index;

}

void set_userName_passWord(struct Mqtt_info* mq, const char* username, const char* passWord) {
	mq->userName = username;
	mq->Password = passWord;
}

char Mqtt_Init(struct Mqtt_info* mq, const char* ip, const char * clientID,int host) {

	mq->pbuf = (unsigned char*)mqtt_malloc(sizeof(unsigned char[pbuf_MAX_SIZE]));			
	if (!mq->pbuf) {
		return -1;
	}


	mq->ip = ip;
	mq->host = host;
	mq->clientID = clientID;
	mq->userName = NULL;
	mq->Password = NULL;
	mq->QoS = QoS0;
	mq->liveTime = 20;

	mq->send_data = tcp_sendData;
	mq->create_connect_msg = create_connect_msg;
	mq->set_userName_passWord = set_userName_passWord;
	mq->create_subscribeTopic_msg = create_subscribeTopic_msg;
	mq->create_publishNew_msg = create_publishNew_msg;
	mq->create_keepLive_msg = create_keepLive_msg;

	return 0;
}


char tcp_sendData(unsigned char* pbuf, int len) {
	/*enter your TCP send func here*/

	return 0;
}



